package com.example.demo.Controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.UUID;

@Slf4j
@Controller
@RequestMapping("/user")
@ResponseBody//默认情况下是返回一个静态页面(历史遗留)，所以此处要通过ResponseBody进行设置，返回一个非静态页面的数据
public class UserController {


    //=============设置接受请求类型===============
    //RequestMapping 即可以支持get请求 也可以支持 post请求
    //若想只支持一种请求，如下设置
    @RequestMapping(method = RequestMethod.POST, value = "/sayhi")
    public String sayhi() {
        return "hello world !";
    }

    //设置只支持 post 请求
    @PostMapping("/sayhi1")
    public String sayhi1() {
        return "hello world 1 !";
    }

    //设置只支持 get 请求
    @GetMapping("/sayhi2")
    public String sayhi2() {
        return "hello world 2 !";
    }


    //===========获取用户请求参数================

    // 1、传递单个参数
    @RequestMapping("/getuserbyid")
    public UserInfo getUserById(Integer id) { //包装类 Integer 支持 null，当前端传递参数为空时程序不会报错，而 int 会
        //保证前端传来的参数和方法里面的参数一致

        //伪代码：不连接数据库，根据 id 获取信息
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setAge(19);
        userInfo.setName("lisi");
        return userInfo;
    }

    //2、传递多个参数时，不现实，这时可以传入一个对象包含所有参数
    @RequestMapping("/reg")
    public String reg(UserInfo userInfo) {
        return "用户信息：" + userInfo;
    }

//     后端参数重命名  @RequestParam是前端传来的参数key ，而UserName是后端设置的参数key
//    @RequestMapping("/rename")
//    public String rename(@RequestParam("ua") String UserName){
//        return "Name:" + UserName;
//    }

    //注意：当设置 @RequestParam 后，前端必须传入参数，不然程序就会报错，可以如下修改!此时前端不传该参数，后端认为是null，不会报错
    @RequestMapping("/rename")
    public String rename(@RequestParam(value = "ua", required = false) @RequestBody String UserName) {
        return "Name:" + UserName;
    }

    // 接受 json格式的请求   @RequestBody
//    @RequestMapping("/rename1")
//    public String rename1(@RequestBody String UserName) {
//        return UserName;
//    }

    @RequestMapping("userjson")
    public String getImgpathJson(@RequestBody UserInfo userInfo) {
        return "用户信息:" + userInfo;
    }

    // 获取URL中参数@PathVariable
    //http://127.0.0.1:8080/user/student/209000804/tanchen
    @RequestMapping("/student/{id}/{name}")  //student为url地址 加了大括号的为参数
    public String getStudentInfo(@PathVariable Integer id, @PathVariable String name) {
        return "ID:" + id + "   Name:" + name;
    }


    // 上传⽂件@RequestPart
    // 示例一个基础场景，客户端用户通过id来修改头像
//    @RequestMapping("/upimg")
//    // @RequestPart：表示上传的文件名参数  MultipartFile：表示用此接收
//    public boolean upImg(Integer id, @RequestPart("img") MultipartFile file)  {
//        try{
//            // 此时是将接收到的文件保存在本地，如果部署到服务器后就是保存到服务器
//            file.transferTo(new File("F:\\db\\img.png"));
//            return true;
//        }catch (IOException e){
////            e.printStackTrace();
//            log.error("上传图片失败" + e.getMessage());
//        }
//        return false;
//    }


    // ======上传文件 优化版 =======
    // 1.设置文件目录，从配置文件中获取
    @Value("${img.path}")
    private String imgpath;

    @RequestMapping("/upimg")
    // @RequestPart：表示上传的文件名参数  MultipartFile：表示用此接收
    public boolean upImg(Integer id, @RequestPart("img") MultipartFile file) {
        // 2.图片名称，不能重复【UUID：全局唯一id 不会重复】
        String fileName = file.getOriginalFilename();//得到原图片名称
        fileName = fileName.substring(fileName.lastIndexOf("."));//得到图片后缀，如.png .gif
        fileName = UUID.randomUUID().toString() + fileName;//得到一个唯一的前缀再与后缀拼起来，就是唯一的图片名称
        try {
            // 此时是将接收到的文件保存在本地，如果部署到服务器后就是保存到服务器
            file.transferTo(new File(imgpath + fileName));
            return true;
        } catch (IOException e) {
            log.error("上传图片失败" + e.getMessage());
        }
        return false;
    }


    //===== 获取所有Cookie =====
    @RequestMapping("/getcookie")
    public void getCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        for (Cookie item : cookies) {
            log.info("Cookie Name:" + item.getName() + "| Cookie Value:" + item.getValue());
        }
    }

    //2.获取想要的 单个Cookie，想要获取多个就写几个注解
    @RequestMapping("getcookie1")
    public String getCookie1(@CookieValue("bite") String cookie)

    {
        return "Cookie Value: " + cookie;
    }


    // ==== 获取header ====
    //1.利用Servlet 方法
    @RequestMapping("/getheader")
    public String getHeader(HttpServletRequest request) {
        return request.getHeader("User-Agent");
    }

    //2.利用注解  @RequestHeader   想要获取多个，就多加几个注解
    @RequestMapping("/getheader1")
    public String getHeader1(@RequestHeader("User-Agent") String header) {
        return "Header：" + header;
    }


    //====== 存储和获取 Session ======
    //1.存储 Session
    @RequestMapping("/setsession")
    public boolean setSession(HttpServletRequest request) {
        boolean result = false;
        HttpSession httpSession = request.getSession(true);
        httpSession.setAttribute("userinfo", "zhangsan");
        result = true;
        return result;
    }

    //2.获取Session
    @RequestMapping("/getsession")
    public String getSession(HttpServletRequest request) {
        String result = null;
        HttpSession httpSession = request.getSession(false);
        if (httpSession != null && httpSession.getAttribute("userinfo") != null) {
            result = (String) httpSession.getAttribute("userinfo");
        }

        return result;
    }

    // 2.1 使用注解 @SessionAttribute 获取 Session
    @RequestMapping("/getsession1")         //设置 required = false，当Session中没有该属性就为null，不设置的话就会报错
    public String getSession1(@SessionAttribute(value = "userinfo", required = false) String session) {
        return session;
    }
}


